import { useState, useRef } from 'react';
import { Button, message, Progress } from 'antd';
import SparkMD5 from 'spark-md5';
import { formatFileSizeUnit } from 'common';
import axios from 'axios';
import { PlayCircleFilled, PauseCircleFilled } from '@ant-design/icons';
const SIZE = 1024 * 1024 * 2;
const UploadingPanel = (props) => {
    const {} = props;
    const [abort, setAbort] = useState(false);
    const [uploadProgress, setUploadProgress] = useState(0); // 上传进度
    const [uploadedIndex, setUploadedIndex] = useState(0); // 上传进度
    const [infoMsg, setInfoMsg] = useState(''); //
     const [fileInfo, setFileInfo] = useState({});
    const InputRef = useRef(null);
    const hash = useRef(null); // 文件hash值
    const partList = useRef([]); // 分片后的文件
    const abortRef = useRef(false);
    // 上传文件
    async function uploadFile() {
        setUploadProgress(0);
        setInfoMsg('文件分解中');
        const file = InputRef.current.files[0];
        await createChunkFile(file);
    }
    //转换文件类型（解析为BUFFER数据）
    function fileParse(file) {
        return new Promise((resolve) => {
            const fileRead = new FileReader();
            fileRead.readAsArrayBuffer(file);
            fileRead.onload = (ev) => {
                resolve(ev.target.result);
            };
        });
    }
    async function createChunkFile(file) {
        if (!file)
            return;
        const buffer = await fileParse(file);
        const spark = new SparkMD5.ArrayBuffer();
        spark.append(buffer);
        hash.current = spark.end();
        const suffix = /\.([0-9a-zA-Z]+)$/i.exec(file.name)[1];
        const list = [];
        const count = Math.ceil(file.size / SIZE);
        const partSize = file.size / count;
        let cur = 0;
        for (let i = 0; i < count; i++) {
            let item = {
                chunk: file.slice(cur, cur + partSize),
                filename: `${hash.current}_${i}.${suffix}`,
            };
            cur += partSize;
            list.push(item);
        }
        partList.current = list;
        getLoadingFiles();
    }
    async function getLoadingFiles() {
        axios.get(`/file/uploaded/count?hash=${hash.current}`)
            .then((res) => {
                if (res.code === 1) {
                    const count = res.data.count;
                    setInfoMsg('文件上传中');
                    setUploadProgress((count * 100 / partList.current.length).toFixed(2));
                    uploadFn(count);
                }
            });
    }
    async function uploadFn(startIndex = 0) {
        if (partList.current.length === 0)
            return;
        abortRef.current = false;
        const requestList = [];
        partList.current.forEach((item, index) => {
            const fn = () => {
                let formData = new FormData();
                formData.append('chunk', item.chunk);
                formData.append('filename', item.filename);
                return axios
                    .post('/file/upload', formData, {
                        headers: { 'Content-Type': 'multipart/form-data' },
                    })
                    .then((res) => {
                        const data = res.data;
                        if (res.code === 1) {
                            setUploadedIndex(index);
                            setUploadProgress((data.index + 1) * 100 / partList.current.length);
                        }
                    })
                    .catch(function () {
                        setAbort(true);
                        message.error('上传失败');
                    });
            };
            requestList.push(fn);
        });
        uploadSend(startIndex, requestList);
    }
    // 上传单个切片
    async function uploadSend(index, requestList) {
        if (abortRef.current)
            return;
        if (index >= requestList.length) {
            uploadComplete();
            return;
        }
        requestList[index] ? await requestList[index]() : setInfoMsg('');
        uploadSend(++index, requestList);
    }
    // 上传完成
    async function uploadComplete() {
        let result = await axios.get(`/file/upload/finish?hash=${hash.current}`);
        if (result.code === 1) {
            message.success('上传成功');
            setInfoMsg('上传完成');
        }
    }
    // 选择文件
    function changeFile() {
        const file = InputRef.current.files[0];
        setFileInfo(file || {});
    }
    return (<div className="uploading-panel">
        <input type="file" onChange={changeFile} ref={InputRef}/>
        {infoMsg && (<span>【{infoMsg}】</span>)}
        {fileInfo.size && (<span>{formatFileSizeUnit(fileInfo.size)}</span>)}
        <Button type="primary" onClick={uploadFile}>
            上传
        </Button>
        <Button type="primary" shape="circle" icon={abort ? <PlayCircleFilled /> : <PauseCircleFilled />} onClick={() => {
            abortRef.current = !abort;
            abort && uploadFn(uploadedIndex + 1);
            setAbort(!abort);
        }}/>
        <div>
            <Progress percent={uploadProgress} status="active"/>
        </div>
    </div>);
};
export default UploadingPanel;
